package top.linyuxb.lycloud.admin.controller;

import jakarta.annotation.Resource;
import jakarta.persistence.criteria.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import top.linyuxb.lycloud.admin.constant.StatusEnum;
import top.linyuxb.lycloud.admin.entity.LyConfEnvEntity;
import top.linyuxb.lycloud.admin.repository.LyConfEnvRepository;
import top.linyuxb.lycloud.admin.repository.LyConfNodeRepository;
import top.linyuxb.lycloud.admin.utils.EntityUtil;
import top.linyuxb.lycloud.admin.utils.ReturnT;
import top.linyuxb.lycloud.admin.web.annotation.PermissionLimit;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Intellij IDEA.
 *
 * @Author: linyuxb
 * @Date: 2024/7/29 14:43
 * @Desc: 环境管理
 */
@Controller
@RequestMapping("/env")
public class EnvController {

    @Resource
    private LyConfEnvRepository lyConfEnvRepository;
    @Resource
    private LyConfNodeRepository lyConfNodeRepository;


    @RequestMapping
    @PermissionLimit(adminuser = true)
    public String index(Model model) {

        List<LyConfEnvEntity> list = lyConfEnvRepository.findByStatusOrderByIdDesc(StatusEnum.VALID.getType());
        model.addAttribute("list", list);

        return "env/env.index";
    }

    @RequestMapping("/save")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> save(LyConfEnvEntity lyConfEnv) {
        // valid
        if (StringUtils.isBlank(lyConfEnv.getEnv())) {
            return new ReturnT<>(500, "Env不可为空");
        }
        if (lyConfEnv.getEnv().length() < 3 || lyConfEnv.getEnv().length() > 50) {
            return new ReturnT<>(500, "Env长度限制为4~50");
        }
        if (StringUtils.isBlank(lyConfEnv.getTitle())) {
            return new ReturnT<>(500, "请输入Env名称");
        }
        // valid repeat
        LyConfEnvEntity existEnv = lyConfEnvRepository.findByEnv(lyConfEnv.getEnv());
        if (existEnv != null) {
            return new ReturnT<>(500, "Env已存在，请勿重复添加");
        }

        lyConfEnvRepository.save(lyConfEnv);
        return ReturnT.SUCCESS;
    }

    @RequestMapping("/update")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> update(LyConfEnvEntity lyConfEnv) {
        // valid
        if (StringUtils.isBlank(lyConfEnv.getEnv())) {
            return new ReturnT<>(500, "Env不可为空");
        }
        if (StringUtils.isBlank(lyConfEnv.getTitle())) {
            return new ReturnT<>(500, "请输入Env名称");
        }
        LyConfEnvEntity existEnv = lyConfEnvRepository.findByIdAndStatus(lyConfEnv.getId(), StatusEnum.VALID.getType());
        BeanUtils.copyProperties(lyConfEnv, existEnv, EntityUtil.getNullPropertyNames(lyConfEnv));
        lyConfEnvRepository.save(existEnv);
        return ReturnT.SUCCESS;
    }

    @RequestMapping("/remove")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> remove(String env) {
        if (StringUtils.isBlank(env)) {
            return new ReturnT<>(500, "参数Env非法");
        }
        // valid
        int listCount = (int) lyConfNodeRepository.count(
                (root, criteriaQuery, cb) -> {
                    List<Predicate> predicates = new ArrayList<>();
                    predicates.add(cb.equal(root.get("env").as(String.class), env));
                    predicates.add(cb.equal(root.get("status").as(Integer.class), StatusEnum.VALID.getType()));
                    return cb.and(predicates.toArray(new Predicate[0]));
                }
        );
        if (listCount > 0) {
            return new ReturnT<>(500, "拒绝删除，该Env下存在配置数据");
        }
        // valid can not be empty
        List<LyConfEnvEntity> allList = lyConfEnvRepository.findByStatusOrderByIdDesc(StatusEnum.VALID.getType());
        if (allList.size() == 1) {
            return new ReturnT<>(500, "拒绝删除, 需要至少预留一个Env");
        }

        int ret = lyConfEnvRepository.deleteByEnv(env);
        return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
    }

}
